from django.db.models import OuterRef, Subquery
from django.shortcuts import render
from django.core.cache import cache
from django.db import models
from rest_framework.viewsets import GenericViewSet
from rest_framework.permissions import IsAuthenticated
from rest_framework_jwt.authentication import JSONWebTokenAuthentication
from friend.paginations import PageNumberPagination
from user.models import relationship,userPhotos,UserProfile
from rest_framework.decorators import action
from user.serializers import UserProfileSerializer
from django.conf import settings
# Create your views here.
from FSJY.utils.buyHighResponse import APIResponse
from .models import Friendship
class FriendViewSet(GenericViewSet):
    permission_classes = [IsAuthenticated]
    authentication_classes = [JSONWebTokenAuthentication]
    pagination_class = PageNumberPagination
    queryset = relationship.objects.all()
    """
        不需要返回通知消息，未接受的通知消息由前端的ws链接接受处理
    """
    @action(detail=False, methods=['get'])
    def get_all_friends(self, request):
        from django.db.models import Case, When, Value, CharField
        from django.db.models.functions import Coalesce
        from socket_chat.models import PrivateMessage
        user=request.user
        param_page=request.GET.get('page')
        if param_page==str(1):
            cache.delete(settings.ALL_FRIEND_CACHE_KEY % user.id)
            print("删除缓存")
        cache_ids=cache.get(settings.ALL_FRIEND_CACHE_KEY % user.id)
        # 构建子查询 查询已接收但未读的消息数量
        unread_count_subquery = PrivateMessage.objects.filter(
            receiver=user,  # 当前用户是接收者
            sender=OuterRef('pk'),  # 好友是发送者
            is_read=False,
            is_received=True
        ).values('sender').annotate(
            count=models.Count('*')
        ).values('count')[:1]
        # 构建子查询，查询最后一条消息的时间
        last_msg_subquery = PrivateMessage.objects.filter(
            models.Q(sender=user, receiver=OuterRef('pk')) |
            models.Q(sender=OuterRef('pk'), receiver=user)
        ).order_by('-timestamp')[:1]
        # 构建子查询，查寻成为好友的时间
        friendship_time = Friendship.objects.filter(
            models.Q(user1=user, user2=OuterRef('pk')) |
            models.Q(user2=user, user1=OuterRef('pk'))
        ).order_by("-created_time").values('created_time')[:1]
        if not cache_ids:
            friends = UserProfile.objects.filter(
                # 反向查询好友关系，friendships_user1反向查询名，__user2获取到真正的实例,related_name只是指向一个位置，__后面才能获取到这个实例
                models.Q(friendships_user1__user2=user.id) |  # 通过反向关系查询好友关系中的user2
                models.Q(friendships_user2__user1=user.id)  # 通过反向关系查询好友关系中的user1
            ).distinct()
            # 构建子查询，获取好友关系中的最后一条消息
            friends_ids = friends.annotate(
                last_msg_content=Subquery(last_msg_subquery.values('content')),
                last_msg_time=Subquery(last_msg_subquery.values('timestamp')),
                # 获取好友关系建立时间
                friendship_time=Subquery(friendship_time),
                # 合并两个时间（优先使用最后消息时间，没有则用好友关系时间）
                combined_time=Coalesce(
                    'last_msg_time',
                    'friendship_time',
                    # 输出一个新的字段
                    output_field=models.DateTimeField()
                )
            ).order_by('-combined_time').values_list("id",flat=True)
            cache_ids=list(friends_ids)
            print(cache_ids)
            cache.set(settings.ALL_FRIEND_CACHE_KEY % user.id,cache_ids,60*60*24)
            # 修改排序字段,用缓存去做分页
        page = self.paginate_queryset(cache_ids)
        print(page)
        if page is not None:
            friends_queryset=UserProfile.objects.filter(id__in=page)
            finally_queryset=friends_queryset.annotate(
                last_msg_content=Subquery(last_msg_subquery.values('content')),
                last_msg_time=Subquery(last_msg_subquery.values('timestamp')),
                unreadCount=Coalesce(Subquery(unread_count_subquery), 0),
                # 获取好友关系建立时间
                friendship_time=Subquery(friendship_time),
                # 合并两个时间（优先使用最后消息时间，没有则用好友关系时间）
                combined_time=Coalesce(
                    'last_msg_time',
                    'friendship_time',
                    # 输出一个新的字段
                    output_field=models.DateTimeField()
                )
            )
            serializer = UserProfileSerializer(finally_queryset, many=True)
            return self.get_paginated_response(serializer.data)
        return APIResponse(code=200,message="没有更多了")
#     关于好友页目前最合适的方案是后端转发消息时携带发送者的id，前端判断messageList中是否存在这个id，
#     存在则直接添加，不存在则需要查询发送者的信息
    @action(detail=False, methods=['get'])
    def get_friend_info(self,request,*args,**kwargs):
        friend_id=request.GET.get('friend_id')
        friend=UserProfile.objects.get(id=friend_id)
        serializer=UserProfileSerializer(friend)
        return APIResponse(code=200,message="获取成功",data=serializer.data)

